package logbrowse;

import java.awt.Color;
import java.awt.Component;

import javax.swing.AbstractListModel;
import javax.swing.DefaultListCellRenderer;
import javax.swing.DefaultListSelectionModel;
import javax.swing.JList;

@SuppressWarnings("serial")
public class ViewLogSelector extends JList {
	private class DoubleModel extends DefaultListSelectionModel {
		private boolean isUpdating;
		
		public DoubleModel() {
			setSelectionMode(SINGLE_INTERVAL_SELECTION);
			isUpdating = false;
		}
		
		@Override
		public void setSelectionInterval(int index0, int index1) {
			if (index0 == index1 && index0 < getModel().getSize() - 1) {
				super.setSelectionInterval(index0, index1 + 1);
				super.setLeadSelectionIndex(index0);
				ViewLogSelector.this.requestFocus();
			} else {
				super.setSelectionInterval(index0, index1);
			}
			/*
			if (isUpdating) {
				super.setSelectionInterval(index0, index1);
			} else {
				addSelectionInterval(index0, index1);
			}
			*/
		}

		@Override
		public void addSelectionInterval(int index0, int index1) {
			this.setSelectionInterval(index0, index1);
			/*
			int new0;
			int new1;
			if (index0 != index1) {
				new0 = index0;
				new1 = index1;
			} else {
				new0 = index1 - 1;
				new1 = index1;
			}
			
			try {
				isUpdating = true;
				super.addSelectionInterval(index0, index1);
				if (new0 - 1 == new1 && new0 >= 0) {
					super.setSelectionInterval(new0, new1);
				} else if (new0 >= 0) {
					super.setSelectionInterval(new0, new0);
					super.addSelectionInterval(new1, new1);
				} else {
					super.setSelectionInterval(new1, new1);
				}
			} finally {
				isUpdating = false;
				fireValueChanged(true);
			}
			*/
		}
		
		@Override
		protected void fireValueChanged(boolean isAdjusting) {
			if (!isUpdating) {
				super.fireValueChanged(isAdjusting);
			}
		}
		
		@Override
		protected void fireValueChanged(int firstIndex, int lastIndex) {
			if (!isUpdating) {
				super.fireValueChanged(firstIndex, lastIndex);
			}
		}

		@Override
		protected void fireValueChanged(int firstIndex, int lastIndex, boolean isAdjusting) {
			if (!isUpdating) {
				super.fireValueChanged(firstIndex, lastIndex, isAdjusting);
			}
		}
	}
	
	public static class Model extends AbstractListModel {
		private LogModel logModel;
		
		Model(LogModel model) {
			logModel = model;
		}

		public Object getElementAt(int index) {
			return logModel.getEntry(index);
		}

		public int getSize() {
			return logModel.getEntryCount();
		}
	}
	
	public static class Renderer extends DefaultListCellRenderer {
		@Override
		public Component getListCellRendererComponent(JList list, Object value,
				int index, boolean isSelected, boolean cellHasFocus) {
			if (value instanceof LogEntry) {
				LogEntry entry = (LogEntry) value;
				String text = entry.getDate() + " (" + entry.getLineCount()
					+ ":" + entry.getModificationCount() + ")";
				Component ret = super.getListCellRendererComponent(list, text,
						index, isSelected, cellHasFocus);
				if (entry.isForced()) {
					ret.setForeground(Color.RED);
				} else if (entry.getErrorMessage() != null) {
					ret.setForeground(Color.BLUE);
				} else {
					ret.setForeground(Color.BLACK);
				}
				return ret;
			} else {
				Component ret = super.getListCellRendererComponent(list, value,
						index, isSelected, cellHasFocus);
				ret.setForeground(Color.BLACK);
				return ret;
			}
		}
	}
	
	public ViewLogSelector(LogModel logModel) {
		this.setSelectionModel(new DoubleModel());
		this.setModel(new Model(logModel));
		this.setCellRenderer(new Renderer());
	}
	
	public LogModel getLogModel() {
		return ((Model) getModel()).logModel;
	}
	
	public void setLogModel(LogModel logModel) {
		clearSelection();
		this.setModel(new Model(logModel));
	}
}
